package pathways.SpeciesSpace;

/**
 * Title:        Pathways
 * Description:  Pure Java version of the Pathways Project.
 * Copyright:    Copyright (c) 2002
 * Company:      Ants Technologies
 * @author Veejay Sani
 * @version 1.0
 */
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.sql.SQLException;
import java.util.Vector;

import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel;

import pathways.Database.Implementation.CDatabase;
import pathways.util.CDBUtil;
import pathways.util.Debug.CDebug;
import pathways.util.helper.CItem;
import pathways.util.helper.CItemComboModel;

public class CSpeciesSpaceView extends JPanel
{
  JLabel lblSpecies = new JLabel();
  JButton cmdSelectSpecies = new JButton();
  JLabel lblTissue = new JLabel();
  JComboBox cboTissue = new JComboBox();
  JLabel lblSubCellularSub = new JLabel();
  JComboBox cboSubCellularSub = new JComboBox();
  JLabel lblOrgan = new JLabel();
  JComboBox cboOrgan = new JComboBox();
  JLabel lblSubCellularProd = new JLabel();
  JComboBox cboSubCellularProd = new JComboBox();
  JLabel lblCell = new JLabel();
  JComboBox cboCell = new JComboBox();
  boolean bEditable = false;
  CItemComboModel cbomdltissue = null;
  CItemComboModel cbomdlorgan = null;
  CItemComboModel cbomdlcell = null;
  CItemComboModel cbomdlsubCellSubs = null;
  CItemComboModel cbomdlsubCellProds = null;
  CtblModel tblmdl = null;
  JButton cmdSave = new JButton();
  CInstantiation instantiation = null;
  CDatabase database = null;
  JScrollPane scrollPane = new JScrollPane();
  JTable tblData = new JTable();
  JFrame parentFrame = null;
  JDialog parentDialog = null;
  IFinished finishListener;
  
  public CSpeciesSpaceView(JFrame owner, IFinished listener)
  {
    parentFrame = owner;
    Init(listener);
  }
  
  public CSpeciesSpaceView(JDialog owner, IFinished listener)
  {
    parentDialog = owner;
    Init(listener);
  }
  
  private void Init(IFinished listener)
  {
    finishListener = listener;
    
    try
    {
      jbInit();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
  
    this.doLayout();
  }
  
  private void jbInit() throws Exception
  {
    lblSpecies.setHorizontalAlignment(SwingConstants.LEFT);
    lblSpecies.setText("Species:");
    lblSpecies.setBounds(new Rectangle(7, 13, 584, 19));
    this.setLayout(null);
    cmdSelectSpecies.setText("Select");
    cmdSelectSpecies.setBounds(new Rectangle(9, 34, 71, 19));
    cmdSelectSpecies.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        cmdSelectSpecies_actionPerformed(e);
      }
    });
    lblTissue.setHorizontalAlignment(SwingConstants.RIGHT);
    lblTissue.setText("Tissue:");
    lblTissue.setVerticalAlignment(SwingConstants.TOP);
    lblTissue.setBounds(new Rectangle(11, 63, 48, 20));
    cboTissue.setBounds(new Rectangle(61, 63, 192, 19));
    lblSubCellularSub.setBounds(new Rectangle(265, 63, 133, 20));
    lblSubCellularSub.setVerticalAlignment(SwingConstants.TOP);
    lblSubCellularSub.setText("Sub-Cellular Substrate:");
    lblSubCellularSub.setHorizontalAlignment(SwingConstants.RIGHT);
    cboSubCellularSub.setBounds(new Rectangle(400, 63, 192, 19));
    lblOrgan.setBounds(new Rectangle(11, 89, 48, 20));
    lblOrgan.setVerticalAlignment(SwingConstants.TOP);
    lblOrgan.setText("Organ:");
    lblOrgan.setHorizontalAlignment(SwingConstants.RIGHT);
    cboOrgan.setBounds(new Rectangle(61, 89, 192, 19));
    lblSubCellularProd.setBounds(new Rectangle(265, 89, 133, 20));
    lblSubCellularProd.setVerticalAlignment(SwingConstants.TOP);
    lblSubCellularProd.setText("Sub-Cellular Product:");
    lblSubCellularProd.setHorizontalAlignment(SwingConstants.RIGHT);
    cboSubCellularProd.setBounds(new Rectangle(400, 89, 192, 19));
    lblCell.setBounds(new Rectangle(11, 113, 48, 20));
    lblCell.setVerticalAlignment(SwingConstants.TOP);
    lblCell.setText("Cell:");
    lblCell.setHorizontalAlignment(SwingConstants.RIGHT);
    cboCell.setBounds(new Rectangle(61, 113, 192, 19));
    cmdSave.setText("Save");
    cmdSave.setBounds(new Rectangle(256, 326, 91, 29));
    cmdSave.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        cmdSave_actionPerformed(e);
      }
    });
    scrollPane.setBounds(new Rectangle(9, 148, 574, 166));
    this.add(lblSpecies, null);
    this.add(cmdSelectSpecies, null);
    this.add(cboTissue, null);
    this.add(lblSubCellularSub, null);
    this.add(cboOrgan, null);
    this.add(lblSubCellularProd, null);
    this.add(cboCell, null);
    this.add(cboSubCellularProd, null);
    this.add(cboSubCellularSub, null);
    this.add(lblCell, null);
    this.add(lblTissue, null);
    this.add(lblOrgan, null);
    this.add(cmdSave, null);
    this.add(scrollPane, null);
    scrollPane.getViewport().add(tblData, null);
  }
  
  public void load(CInstantiation inst, CDatabase db)
  {
    instantiation = inst;
    database = db;
    
    showSpecies(inst.getSpecies());
    this.cmdSelectSpecies.setEnabled(bEditable);
    loadSpace(inst.getSpace(),db);
    loadData(inst.getData());
    
    this.cmdSave.setEnabled(bEditable);
    
    if (bEditable)
    {   
      
    }
    else
    {
    
    }
    
  }
  
  private void loadData(Vector data)
  {
    this.tblmdl = new CtblModel(data);
    this.tblmdl.setEditing(bEditable);
    this.tblData.setModel(tblmdl);
  }
  
  private void loadSpace(CSpace space, CDatabase db)
  {
    this.cboTissue.setEnabled(bEditable);
    this.cboOrgan.setEnabled(bEditable);
    this.cboCell.setEnabled(bEditable);
    this.cboSubCellularSub.setEnabled(bEditable);
    this.cboSubCellularProd.setEnabled(bEditable);
    
    if (bEditable)
    {
      //loadComboBox(this.cboTissue,this.cbomdltissue,CDBUtil.getTissues(db));
      cbomdltissue = new CItemComboModel(CDBUtil.getTissues(db));
      cboTissue.setModel(cbomdltissue);
      
      //loadComboBox(this.cboOrgan,this.cbomdlorgan,CDBUtil.getOrgans(db));
      cbomdlorgan = new CItemComboModel(CDBUtil.getOrgans(db));
      cboOrgan.setModel(cbomdlorgan);
      
      //loadComboBox(this.cboCell,this.cbomdlcell,CDBUtil.getCells(db));
      cbomdlcell = new CItemComboModel(CDBUtil.getCells(db));
      cboCell.setModel(cbomdlcell);
      
      //loadComboBox(this.cboSubCellularSub,this.cbomdlsubCellSubs,CDBUtil.getSubCellSubs(db));
      cbomdlsubCellSubs = new CItemComboModel(CDBUtil.getSubCellSubs(db));
      cboSubCellularSub.setModel(cbomdlsubCellSubs);
      
      //loadComboBox(this.cboSubCellularProd,this.cbomdlsubCellProds,CDBUtil.getSubCellProds(db));
      cbomdlsubCellProds = new CItemComboModel(CDBUtil.getSubCellProds(db));
      cboSubCellularProd.setModel(cbomdlsubCellProds);
      
      selectItemInCombo(this.cboTissue,space.getTissue());
      selectItemInCombo(this.cboOrgan,space.getOrgan());
      selectItemInCombo(this.cboCell,space.getCell());
      selectItemInCombo(this.cboSubCellularSub,space.getSubCellularSubstrate());
      selectItemInCombo(this.cboSubCellularProd,space.getSubCellularProduct());
    }
    else
    {      
      putValueInCombo(this.cboTissue,this.cbomdltissue,space.getTissue().getValue());
      putValueInCombo(this.cboOrgan,this.cbomdlorgan,space.getOrgan().getValue());
      putValueInCombo(this.cboCell,this.cbomdlcell,space.getCell().getValue());
      putValueInCombo(this.cboSubCellularSub,this.cbomdlsubCellSubs,space.getSubCellularSubstrate().getValue());
      putValueInCombo(this.cboSubCellularProd,this.cbomdlsubCellProds,space.getSubCellularProduct().getValue());
    }   
  }

  private void selectItemInCombo(JComboBox cbo, CItem item)
  {
    ComboBoxModel mdl = cbo.getModel();
    CItem temp = null;
    
    for (int i = 0; i < mdl.getSize(); i++)
    {
      temp = (CItem)mdl.getElementAt(i);
      
      if (item.equals(temp))
      {
        cbo.setSelectedIndex(i);
        return; 
      }
    } 
    
    cbo.setSelectedItem(null); 
  }
    
  private void loadComboBox(JComboBox cbo, CItemComboModel mdl, Vector items)
  {
    mdl = new CItemComboModel(items);
    cbo.setModel(mdl);
  }
  
  private void putValueInCombo(JComboBox cbo, CItemComboModel mdl, String value)
  {
    Vector v = new Vector();
    v.add(value);
         
    mdl = new CItemComboModel(v);
    cbo.setModel(mdl);
  }
  
  public boolean isEditable()
  {
    return bEditable; 
  } 
  
  public void setEditable(boolean editable)
  {
    bEditable = editable; 
  }

  public boolean isSaved()
  {
    return (this.instantiation.getID() > 0);  
  }
  
  void cmdSave_actionPerformed(ActionEvent e)
  {
    if (isOK())
    {
      CItem tissue = (CItem)this.cbomdltissue.getSelectedItem();
      CItem organ = (CItem)this.cbomdlorgan.getSelectedItem();
      CItem cell = (CItem)this.cbomdlcell.getSelectedItem();
      CItem subCellSub = (CItem)this.cbomdlsubCellSubs.getSelectedItem();
      CItem subCellProd = (CItem)this.cbomdlsubCellProds.getSelectedItem();
      CSpace space = instantiation.getSpace();
      
      space.setTissue(tissue);
      space.setOrgan(organ);
      space.setCell(cell);
      space.setSubCellularSubstrate(subCellSub);
      space.setSubCellularProduct(subCellProd);
      space.save(database);
      
      try {
        database.getConnection().beginTrans();
        
        if (instantiation.save(database))
        {
           database.getConnection().commitTrans();
           JOptionPane.showMessageDialog(this,"Successfully saved");
           finishListener.finished();
        }
        else
        {
           database.getConnection().rollbackTrans();
           JOptionPane.showMessageDialog(this,"Unable to save.");
        }
        
      } catch (SQLException sqle) {
        CDebug.println(this, "cmdSave_actionPerformed() Exception: " + sqle.toString()); 
      }
    }
  }
  
  private boolean isOK()
  {
    // must select a species
    // must select every box for space
    
    if (instantiation.getSpecies().getID() <= 0)
    {
      JOptionPane.showMessageDialog(this,"Please select a species.","Warning",JOptionPane.WARNING_MESSAGE);
      return false;
    }
    
    if (this.cboTissue.getSelectedIndex() < 0)
    {
      JOptionPane.showMessageDialog(this,"Please select a tissue.","Warning",JOptionPane.WARNING_MESSAGE);
      return false;
    }

    if (this.cboOrgan.getSelectedIndex() < 0)
    {
      JOptionPane.showMessageDialog(this,"Please select an organ.","Warning",JOptionPane.WARNING_MESSAGE);
      return false;
    }
    
    if (this.cboCell.getSelectedIndex() < 0)
    {
      JOptionPane.showMessageDialog(this,"Please select a cell.","Warning",JOptionPane.WARNING_MESSAGE);
      return false;
    }
    
    if (this.cboSubCellularSub.getSelectedIndex() < 0)
    {
      JOptionPane.showMessageDialog(this,"Please select a sub-cellular substrate.","Warning",JOptionPane.WARNING_MESSAGE);
      return false;
    }
    
    if (this.cboSubCellularProd.getSelectedIndex() < 0)
    {
      JOptionPane.showMessageDialog(this,"Please select a sub-cellular product.","Warning",JOptionPane.WARNING_MESSAGE);
      return false;
    }
    
    return true;  
  }
  
  void cmdSelectSpecies_actionPerformed(ActionEvent e)
  {
    CSelectSpecies select;
    
    if (parentFrame != null)
       select = new CSelectSpecies(parentFrame,database);
    else
       select = new CSelectSpecies(parentDialog,database);
       
    select.show();
    
    CItem species = select.getSelectedSpecies();
    
    if (species != null)
    {
      instantiation.setSpecies(species); 
      showSpecies(species);
    }
    
    /*ResultSet rs = database.getSelect().getSpecies(1);
    
    try {
      rs.next();
      CItem item = new CItem(rs.getInt(1),rs.getString(2));
      instantiation.setSpecies(item);
      showSpecies(item);
    } catch (SQLException sqle) {
      CDebug.println(this, "cmdSelectSpecies_actionPerformed() Exception: " + sqle.toString()); 
    }*/
    
  }
  
  private void showSpecies(CItem species)
  {
    this.lblSpecies.setText("Species: " + species.getValue()); 
  }
}

class CtblModel extends AbstractTableModel
{
  private Vector data;
  private boolean allowEditing = false;
   
  public CtblModel(Vector v)
  {
    data = v;  
  }
  
  public void setEditing(boolean edit)
  {
    allowEditing = edit;  
  }
  
  public boolean isEditable()
  {
    return allowEditing;  
  }
  
  public void setData(Vector v)
  {
    data = v;  
  }
  
  public Vector getData()
  {
    return data;  
  }
  
  public int getRowCount()
  {
    return data.size();
  }
  
  public int getColumnCount()
  {
    return 2; 
  }
  
  public String getColumnName(int column)
  {
    if (column == 0)
       return "Name";
    else if (column == 1)
       return "Value";
       
    return "Invalid Column";
  }
  
  public Object getValueAt(int row, int column)
  {
    CData dataObj = (CData)data.get(row);
    
    if (column == 0)
    {
      return dataObj.getField().getName();  
    }
    else if (column == 1)
    {
      return dataObj.getValue();
    }
    
    return "Error - Unknown column";
  }

  public boolean isCellEditable(int rowIndex, int columnIndex)
  {
    if (columnIndex == 1)
       return allowEditing;
    else
      return false; 
  }
  
  public void setValueAt(Object aValue, int rowIndex, int columnIndex)
  {
    if (columnIndex == 1)
    {
      CData dataObj = (CData)data.get(rowIndex);
      dataObj.setValue(aValue.toString());
    }  
  }
}